package ModelLayer;

import java.util.HashMap;
import java.util.ArrayList;
/**
 * AddressBook functions as a container for Person objects. It's set up as a singleton, to avoid the creation of several AddressBook objects.
 *
 * @author Anders A.P, Anna K., Danny M.P., Jakob K., Mie P.  
 * @version 1.0
 */
public class AddressBook
{
    private HashMap<String, Person> addressBook;
    private static AddressBook      instance;
    /**
     * Constructs one, and is limited to one construction of class AddressBook, taking no parameters but initializing addressBook collection.
     */
    private AddressBook()
    {
        addressBook = new HashMap<String, Person>();   
    }
    
    /**
     * creates a singleton instance which through its constructor creates the singleton collection.
     *
     * @return  instance    Returns the singleton instance to the caller.
     */
    public static AddressBook getInstance()
    {
        if(instance == null) {
            instance = new AddressBook();
        }
        return instance;
    }
    
    /**
     * Adds a Person object to the singleton collection. Uses person ID and Person object as key and value respectively.
     *
     * @param   p   An instance of class Person.
     */
    public void addPerson(Person p)
    {
        addressBook.put(p.getID(), p); 
    }
    
    /**
     * Finds a Person object in the singleton collection by ID key.
     *
     * @param   id          The mapping key, used for finding a Person object value mapped to this key specifically.
     * @return  Person      Returns a person object mapped to the key value supplied as a parameter.
     * @throw   Exception   Throws an exception caught by the UI if no Person object is mapped to the key.
     */
    public Person getPersonID(String id)
    {
            if(addressBook.get(id) != null) {
                return addressBook.get(id);
            }
            else {
                throw new IllegalArgumentException("Person not found");
            }
    }
    
    /**
     * Finds all Person objects with a String value matching the supplied parameter in the collection.
     *
     * @param   name        A String value of the name field in the Person object.
     * @return  ArrayList   A collection of all Person objects matching the parameter supplied. 
     */
    public ArrayList<Person> getPersonName(String name)
    {
        ArrayList<Person> matches = new ArrayList<Person>();
        for(Person p : addressBook.values()) {
            if(name.equals(p.getName())) {
                matches.add(p);
            }
        }
        return matches;
    }
        
    /**
     * Removes a Person object from the singleton collection, identifying it by the key value supplied as a parameter.
     *
     * @param   id          The key value used to locate the mapping of a Person object.
     * @return  true        If the id matched a key in the collection.
     * @throw   Exception   If addressBook does not contain the supplied key.
     */
    public boolean deletePerson(String id)
    {
        if(addressBook.containsKey(id)) {
            addressBook.remove(id);
            return true;
        }
        else {
            throw new IllegalArgumentException("Person not found");
        }
    }
    
    /**
     * Returns a list of all Person objects in the singleton collection.
     *
     * @return  ArrayList   Returns a list view of all Person objects in the HashMap.
     */
    public ArrayList<Person> listAll()
    {
        ArrayList<Person> persons = new ArrayList<Person>();
        for(Person p : addressBook.values()) {
            persons.add(p);
        }
        return persons;
    }

}
